home *** CD-ROM | disk | FTP | other *** search
- unit Table2;
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, DB, DBTables;
-
- type
- TCalcFieldsEvent =
- procedure (DataSet: TDataSet; var DoDefault: Boolean) of object;
-
- TNewTable2 = class(TTable)
- private
- FOnCalcFields: TCalcFieldsEvent;
- procedure OldOnCalcFields(DataSet: TDataSet);
- public
- constructor Create(AOwner: TComponent); override;
- procedure MakeFields(const FieldNames: array of String);
- procedure MakeCalculatedField(const FieldName: String;
- DataType: TFieldType; Size: Word);
- published
- property OnCalcFields: TCalcFieldsEvent
- read FOnCalcFields write FOnCalcFields;
- end;
-
- procedure Register;
-
- implementation
-
- constructor TNewTable2.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- DatabaseName := 'DBDEMOS';
- TableName := 'CUSTOMER';
- MakeFields(['Company', 'CustNo', 'TaxRate']);
- MakeCalculatedField('Taxable', ftBoolean, 0);
- inherited OnCalcFields := OldOnCalcFields;
- end;
-
- procedure TNewTable2.MakeFields(const FieldNames: array of String);
- var
- CopyTable: TTable;
- Field, CopyField: TField;
- Loop: Byte;
- begin
- { Only make objects when asked by user }
- { not when reading in from form stream }
- if not (csLoading in Owner.ComponentState) then
- begin
- { Make normal table object (it will have all fields available }
- { If we were to rely on this table, after the first field }
- { object is added, we wouldn't see any other fields) }
- CopyTable := TTable.Create(nil);
- try
- { Set up copy table properties and open it }
- CopyTable.DatabaseName := DatabaseName;
- CopyTable.TableName := TableName;
- CopyTable.Open;
- { Loop for each new field object }
- for Loop := Low(FieldNames) to High(FieldNames) do
- begin
- { Find the normal run-time field }
- CopyField := CopyTable.FieldByName(FieldNames[Loop]);
- { Construct a new object of the appropriate class type }
- { This is the thing which will end up in the Object Inspector }
- Field := TFieldClass(CopyField.ClassType).Create(Owner);
- { Tie it to a field }
- Field.FieldName := FieldNames[Loop];
- { Give the object a name }
- Field.Name := Name + FieldNames[Loop];
- { Set the size up correctly }
- Field.Size := CopyField.Size;
- { Insert the field in this table }
- Field.DataSet := Self;
- end;
- finally
- { Finished with the copy table now }
- CopyTable.Free;
- end;
- end;
- end;
-
- procedure TNewTable2.MakeCalculatedField(const FieldName: String;
- DataType: TFieldType; Size: Word);
- var
- Field: TField;
- begin
- { Only make objects when asked by user }
- { not when reading in from form stream }
- if not (csLoading in Owner.ComponentState) then
- { Use a field definition object to save code }
- with TFieldDef.Create(nil, FieldName, DataType, Size, False, 0) do
- try
- { Make appropriate field object }
- Field := CreateField(Owner);
- Field.Calculated := True;
- { Sort its name out, so it will appear in the Object Inspector }
- Field.Name := Name;
- { Insert it into the table's field list }
- Field.DataSet := Self;
- finally
- Free;
- end;
- end;
-
- procedure TNewTable2.OldOnCalcFields(DataSet: TDataSet);
- var
- DoDefault: Boolean;
- begin
- DoDefault := True;
- if Assigned(FOnCalcFields) then
- FOnCalcFields(DataSet, DoDefault);
- if DoDefault then
- begin
- { The calculated field calculation needs to be placed here }
- FieldByName('Taxable').AsBoolean := FieldByName('TaxRate').AsFloat > 0;
- end;
- end;
-
- procedure Register;
- begin
- RegisterComponents('Samples', [TNewTable2]);
- end;
-
- end.
-
-